import type { Directive, App, ObjectDirective } from 'vue';

/**
 * 鼠标进入文字下划线动画
 * */

// 定义指令选项类型
interface SlideUnderlineOptions {
  color?: string; // 下划线颜色
  height?: string; // 下划线高度
  duration?: number; // 动画时长（秒）
  direction?: 'left' | 'right'; // 动画方向
  hoverColor?: string; // 文字hover颜色
}

// 默认配置
const DEFAULT_OPTIONS: SlideUnderlineOptions = {
  color: '#222',
  height: '2px',
  duration: 0.4,
  direction: 'left',
};

// 生成唯一类名，避免样式冲突
const BASE_CLASS = 'v-slide-underline';
const UNDERLINE_CLASS = `${BASE_CLASS}__underline`;

// 创建样式并注入到文档
const injectStyles = () => {
  if (document.getElementById(`${BASE_CLASS}-styles`)) return;

  const style = document.createElement('style');
  style.id = `${BASE_CLASS}-styles`;
  style.textContent = `
    .${BASE_CLASS} {
      position: relative;
      text-decoration: none;
      cursor: pointer;
      transition: color 0.3s;
    }

    .${UNDERLINE_CLASS} {
      position: absolute;
      left: 0;
      bottom: 0;
      width: 0;
      transition-property: width;
      transition-timing-function: ease-in-out;
    }

    .${BASE_CLASS}:hover .${UNDERLINE_CLASS} {
      width: 100%;
    }
  `;
  document.head.appendChild(style);
};

// 指令逻辑
const directive: ObjectDirective<HTMLElement, SlideUnderlineOptions> = {
  // 初始化时调用
  mounted(el, binding) {
    // 注入样式
    injectStyles();

    // 合并配置（默认配置 + 指令参数）
    const options = { ...DEFAULT_OPTIONS, ...binding.value };

    // 创建下划线元素
    const underline: any = document.createElement('span');
    underline.className = UNDERLINE_CLASS;
    underline.style.backgroundColor = options.color;
    underline.style.height = options.height;
    underline.style.transitionDuration = `${options.duration}s`;
    underline.style.transformOrigin = options.direction === 'left' ? 'left center' : 'right center';

    // 给元素添加基础类名
    el.classList.add(BASE_CLASS);

    // 设置文字hover颜色（如果有）
    if (options.hoverColor) {
      el.style.color = 'inherit'; // 继承默认颜色
      const style = document.createElement('style');
      style.textContent = `
        .${BASE_CLASS}[data-v-slide-underline="${el.dataset.vSlideUnderline}"]:hover {
          color: ${options.hoverColor};
        }
      `;
      // 生成唯一标识避免样式冲突
      el.dataset.vSlideUnderline = Math.random().toString(36).slice(2, 8);
      document.head.appendChild(style);
    }

    // 添加下划线元素到目标元素
    el.appendChild(underline);

    // 存储下划线元素供后续更新使用
    (el as any)[`${BASE_CLASS}_underline`] = underline;
  },

  // 当指令参数更新时调用
  updated(el, binding) {
    if (!binding.value) return;

    const underline = (el as any)[`${BASE_CLASS}_underline`];
    if (!underline) return;

    // 更新样式
    if (binding.value.color) {
      underline.style.backgroundColor = binding.value.color;
    }
    if (binding.value.height) {
      underline.style.height = binding.value.height;
    }
    if (binding.value.duration) {
      underline.style.transitionDuration = `${binding.value.duration}s`;
    }
    if (binding.value.direction) {
      underline.style.transformOrigin =
        binding.value.direction === 'left' ? 'left center' : 'right center';
    }
  },

  // 元素卸载时清理
  unmounted(el) {
    const underline = (el as any)[`${BASE_CLASS}_underline`];
    if (underline) {
      el.removeChild(underline);
      delete (el as any)[`${BASE_CLASS}_underline`];
    }
    el.classList.remove(BASE_CLASS);
  },
};

// 注册为全局指令
export const setupSlideUnderlineDirective = (app: App) => {
  app.directive('slide-underline', directive);
};

export default directive;
